/*---------------------------------------------------------------------------------

---------------------------------------------------------------------------------*/
#include <nds.h>
#include <dswifi9.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include <fat.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BSZ (32*1024)

int openServer()
{
    struct sockaddr_in myaddr;
    int mysocket;
    mysocket = socket( AF_INET, SOCK_STREAM, 0 );
    iprintf("Created Socket!\n");
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(80);
    myaddr.sin_addr.s_addr= INADDR_ANY;

    bind(mysocket, (struct sockaddr *)&myaddr,sizeof(myaddr));
    listen(mysocket,1);

    return mysocket;
}

int acceptConnection(int serverSocket)
{
    struct sockaddr_in otheraddr;
    int socket,len;

    len = sizeof(otheraddr);
    socket = accept(serverSocket, (struct sockaddr *)&otheraddr, &len);

    return socket;
}

char buf[BSZ];
int recvFile(int socket)
{
    unsigned int len=0,i=0,sz=0;
    char b,n=0;

    while(1) {
        int rdlen = recv(socket, &b, 1, 0 );
        if(rdlen==-1) return 0;
        buf[sz]=b;
        if(!b) break;
        ++sz;
    }

    iprintf("recebendo %s\n",buf);
    FILE *f = fopen(buf,"wb");
    if(!f) {
      iprintf("erro criando arquivo %s\n",buf);
      return 0;
    }

    for(n=0;n<4;n++) {
        int rdlen = recv(socket, &b, 1, 0 );
        if(rdlen==-1) goto ERR;
        len += b<<(n*8);
    }
    iprintf("%d bytes\n",len);

    iprintf("reading ");
    sz=0;
    while(i<len) {
        int rdlen = recv(socket, buf+sz, BSZ-sz, 0 );
        //iprintf("rdlen %d\n",rdlen);
        iprintf(".");
        if(rdlen<0) goto ERR;
        sz+=rdlen;
        i+=rdlen;
        if( (sz==BSZ) || (i>=len) ) {
            fwrite(buf,1,sz,f);
            if(sz==BSZ) sz=0;
            if(i>=len) break;
        }
    }
    fclose(f);
    iprintf("received!\n");
    send(socket, "ok", 3, 0);

    return 1;

ERR:
    fclose(f);
    return 0;
//    iprintf("rdlen %d\n",rdlen);
// if(rdlen>0) iprintf("data: %s\n",buf);
//    send( othersocket, "teste 123", 10, 0 );
}


//---------------------------------------------------------------------------------
int main(void) {
//---------------------------------------------------------------------------------

    consoleDemoInit();  //setup the sub screen for printing
    if(!fatInitDefault()) {
      iprintf("libfat error\n");
    } else {
        iprintf("\n\n\tSimple Wifi Connection Demo\n\n");
        iprintf("Connecting via WFC data ...\n");

        if(!Wifi_InitDefault(WFC_CONNECT)) {
            iprintf("Failed to connect!");
        } else {
	    iprintf("Connected\n\n");
	    struct in_addr ip, gateway, mask, dns1, dns2;

	    ip = Wifi_GetIPInfo(&gateway, &mask, &dns1, &dns2);
		
	    iprintf("ip     : %s\n", inet_ntoa(ip) );
	    iprintf("gateway: %s\n", inet_ntoa(gateway) );
	    iprintf("mask   : %s\n", inet_ntoa(mask) );
	    iprintf("dns1   : %s\n", inet_ntoa(dns1) );
	    iprintf("dns2   : %s\n", inet_ntoa(dns2) );

            int ss = openServer();
            int s = acceptConnection(ss);
            recvFile(s);
	}
    }
	
    while(1) {
        swiWaitForVBlank();
    }

    return 0;
}

















